import axios from "axios";
import React, { useEffect, useState } from "react";
import { debounce } from "lodash";
import {
  Table,
  Button,
  message as antdMessage,
  Popconfirm,
  Form,
  Input,
  InputNumber,
  Typography,
  Row,
  Col,
  Space,
  Modal,
} from "antd";
import { useLocation, useSearchParams } from "react-router-dom";
import { useTranslation } from "react-i18next";

interface ListState {
  id: string;
  tel: string;
  address: string;
  nickname: string;
  type: string;
}

interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
  editing: boolean;
  dataIndex: string;
  title: any;
  inputType: "number" | "text";
  record: ListState;
  index: number;
  children: React.ReactNode;
}

const EditableCell: React.FC<EditableCellProps> = ({
  editing,
  dataIndex,
  title,
  inputType,
  record,
  index,
  children,
  ...restProps
}) => {
  const inputNode = inputType === "number" ? <InputNumber /> : <Input />;

  return (
    <td {...restProps}>
      {editing ? (
        <Form.Item
          name={dataIndex}
          style={{ margin: 0 }}
          rules={[
            {
              required: true,
              message: `Please Input ${title}!`,
            },
          ]}
        >
          {inputNode}
        </Form.Item>
      ) : (
        children
      )}
    </td>
  );
};

const Index: React.FC = () => {
  const { t } = useTranslation();
  const [searchParams, setSearchParams] = useSearchParams();
  const location = useLocation();
  const keyword = searchParams.get("keyword") as string;
  const type = searchParams.get("type") || "全部";

  const typesList = [
    "全部",
    "衬衫",
    "羊毛衫",
    "雪纺衫",
    "裤子",
    "高跟鞋",
    "袜子",
  ];
  // 数据容器
  const [list, setList] = useState<ListState[]>([]);
  // 临时存储选中数据
  const [selectedID, setSelectedID] = useState<string[]>([]);
  const [editingKey, setEditingKey] = useState("");

  const [form] = Form.useForm();

  const isEditing = (record: ListState) => record.id === editingKey;

  const edit = (record: Partial<ListState>) => {
    form.setFieldsValue({
      ...record,
    });
    setEditingKey(record.id as string);
  };

  const cancel = () => {
    setEditingKey("");
  };
  // 列表列数据
  const columns = [
    {
      title: "ID",
      dataIndex: "id",
      key: "id",
      editable: true,
    },
    // "nickname": "昵称",
    // "tel": "电话",
    // "address": "地址",
    // "type": "类型",
    // "modify": "编辑",
    // "delete": "删除",
    // "selectDelete": "批量删除"
    {
      title: t("listManage.type"),
      dataIndex: "type",
      key: "type",
      editable: true,
    },
    {
      title: t("listManage.nickname"),
      dataIndex: "nickname",
      key: "nickname",
      editable: true,
    },
    {
      title: t("listManage.tel"),
      dataIndex: "tel",
      key: "tel",
      editable: true,
    },
    {
      title: t("listManage.address"),
      dataIndex: "address",
      key: "address",
      editable: true,
    },
    {
      title: (
        <div>
          {selectedID.length === 0 ? (
            <div>操作</div>
          ) : (
            <Button
              type="primary"
              danger
              onClick={() => {
                Modal.confirm({
                  title: "警告",
                  content: "确认删除选中的数据吗？",
                  onOk() {
                    deleteSelected();
                  },
                  cancelText: "取消",
                });
              }}
            >
              {t("listManage.selectDelete")}
            </Button>
          )}
        </div>
      ),
      dataIndex: "operation",
      render: (_: any, record: ListState) => {
        const editable = isEditing(record);
        return editable ? (
          <span>
            <Typography.Link
              onClick={() => save(record.id)}
              style={{ marginRight: 8 }}
            >
              Save
            </Typography.Link>
            <Popconfirm title="Sure to cancel?" onConfirm={cancel}>
              <a>Cancel</a>
            </Popconfirm>
          </span>
        ) : (
          <Space>
            <Button disabled={editingKey !== ""} onClick={() => edit(record)}>
              {t("listManage.modify")}
            </Button>
            <Popconfirm
              title="确认要删除吗？"
              onConfirm={() => deleteData(record.id)}
            >
              <Button
                type="primary"
                danger
                // onClick={() => deleteData(reword.id)}
              >
                {t("listManage.delete")}
              </Button>
            </Popconfirm>
          </Space>
        );
      },
    },
  ];

  // 数据请求函数
  const fetchData = async () => {
    const params = {
      keyword,
      type,
    };
    // 发送请求
    const resp = await axios.get("/lists", { params });
    // 保存数据
    setList(resp.data.data);
  };

  // 数据删除函数
  const deleteData = async (id: string) => {
    // 发送删除请求
    const resp = await axios.delete("/list", { params: { id } });
    const { code, message } = resp.data;
    if (code === 200) {
      fetchData();
      antdMessage.success(message);
    }
  };

  // 删除选中数据
  const deleteSelected = async () => {
    // 删除
    const resp = await axios.delete("/list", {
      params: { id: selectedID.join(",") },
    });
    const { code, message } = resp.data;
    if (code === 200) {
      fetchData();
      antdMessage.success(message);
    }
  };

  const mergedColumns = columns.map((col) => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: (record: ListState) => ({
        record,
        inputType: col.dataIndex === "age" ? "number" : "text",
        dataIndex: col.dataIndex,
        title: col.title,
        editing: isEditing(record),
      }),
    };
  });

  const save = async (key: React.Key) => {
    try {
      const row = (await form.validateFields()) as ListState;
      const resp = await axios.post("/list/" + row, row);
      if (resp.data.code === 200) {
        antdMessage.success(resp.data.message);
        const newData = [...list];
        const index = newData.findIndex((item) => key === item.id);
        if (index > -1) {
          const item = newData[index];
          newData.splice(index, 1, {
            ...item,
            ...row,
          });
          setList(newData);
          setEditingKey("");
        } else {
          newData.push(row);
          setList(newData);
          setEditingKey("");
        }
      }
    } catch (errInfo) {
      console.log("Validate Failed:", errInfo);
    }
  };

  // 副作用函数 刚进来发送一次请求
  useEffect(() => {
    // 请求
    fetchData();
  }, [location]);

  /****************** 搜索 *********************/
  const onPressEnter = (value: string) => {
    if (value) setSearchParams({ keyword: value, type });
    else setSearchParams({ type });
  };

  return (
    <div>
      <Row style={{ alignItems: "center", margin: "10px 0" }}>
        <Col span={1} style={{ textAlign: "right", paddingRight: 20 }}>
          搜索:
        </Col>
        <Col span={23}>
          <Input.Search
            defaultValue={keyword || ""}
            onPressEnter={debounce(
              (e) => onPressEnter((e.target as HTMLInputElement).value),
              400
            )}
          ></Input.Search>
        </Col>
      </Row>
      <Row style={{ alignItems: "center", margin: "10px 0" }}>
        <Col span={1} style={{ textAlign: "right", paddingRight: 20 }}>
          类型:
        </Col>
        <Col span={23}>
          <Space>
            {typesList.map((v, i) => {
              return (
                <Button
                  key={i}
                  type={type === v ? "primary" : "default"}
                  onClick={() => {
                    keyword
                      ? setSearchParams({ type: v, keyword })
                      : setSearchParams({ type: v });
                  }}
                >
                  {v}
                </Button>
              );
            })}
          </Space>
        </Col>
      </Row>
      <Form form={form} component={false}>
        <Table
          scroll={{ y: 400 }}
          components={{
            body: {
              cell: EditableCell,
            },
          }}
          bordered
          rowClassName="editable-row"
          pagination={{
            onChange: cancel,
          }}
          dataSource={list}
          columns={mergedColumns}
          rowKey="id"
          rowSelection={{
            onChange(selectedRowKeys, selectedRows) {
              setSelectedID(selectedRowKeys as string[]);
            },
          }}
        />
      </Form>
    </div>
  );
};

export default Index;
